#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#   Experiment with Streams and Processes for core4 module
#   http://devel.ownport.net/2012/01/ore4-pyflowctrl.html
#

__author__ = 'Andrey Usov <http://devel.ownport.net>'
__meta__ = { 'library': 'pyflowctrl', }

import pprint

from pyflowctrl.core4 import Packet, Stream, Process, ProcessFlow
from pyflowctrl.core4 import EmptyStream
from pyflowctrl.core4 import WAITING, PROCESSING

# ----------------------------------------------------
# Processes 
class TestProcess(Process):
    ''' Test Process '''
    def __init__(self):
        super(TestProcess, self).__init__()
        self.input = Stream()
        self.output = Stream()

    def main(self):
        while True:
            try:
                packet = self.input.get()
            except EmptyStream:
                yield WAITING
                continue

            packet.id = id(packet)
            packet.name = 'packet'
            packet.url = 'http://example.com'

            self.output.put(packet)
            yield PROCESSING

class Printer(Process):
    def __init__(self):
        super(Printer, self).__init__()
        self.input = Stream()
    
    def main(self):
        while True:
            try:
                packet = self.input.get()
            except EmptyStream:
                yield WAITING
                continue

            #print packet.dump()
            pprint.pprint(packet.dump())
            print
            yield PROCESSING

# ----------------------------------------------------
# Packet handlers 
def p1p2_handler(packet):
    # process1 -> process2
    packet.set_namespace('test-env1')
    packet['test-env1'].name = packet.name
    packet['test-env1'].url = packet.url
    del packet.name
    del packet.url
    return packet

def p2prn_handler(packet):
    # process2 -> printer
    packet.set_namespace('test-env2')
    packet['test-env2'].name = packet.name
    packet['test-env2'].url = packet.url
    del packet.name
    del packet.url
    return packet


# -------------------------------------------------
# Process Flow network 
network = {
    'processes': {
        'process1': TestProcess(),
        'process2': TestProcess(),
        'printer': Printer(),
    },
    'links': {
        ('process1.output', 'process2.input', p1p2_handler),
        ('process2.output', 'printer.input', p2prn_handler),
    }
}

# ----------------------------------------------------
# Main 

flow = ProcessFlow()
flow.upload(network)
for i in xrange(10):
    flow.pmap['process1'].input.put(Packet(counter=i))
flow.run()



